

package tkatva.consulting.jmxpoller

import javax.management._
import javax.management.remote._
import tkatva.consulting.jmxconnection.beans._
import scala.collection.mutable.ListBuffer
import scala.collection.mutable.HashMap

/*
 * Author Tuomas Katva
 * 
 * This class connects JmxServer (ServiceMix) and retrieves information from the server
 * 
 */

class JmxPoller {

  var srvUrl : String = null
  var servicePword : String = null
  var serviceUsr : String = null
  var mbsc : MBeanServerConnection = null
  
  def createConnection() = {
    var serviceUrl : JMXServiceURL = new JMXServiceURL(srvUrl)
    val usrPword = new Array[String](2)
    usrPword(0) = serviceUsr
    usrPword(1) = servicePword
    var hmm  = new java.util.HashMap[String,Array[String]]()
    hmm.put(JMXConnector.CREDENTIALS, usrPword)
    val jmxc : JMXConnector = JMXConnectorFactory.connect(serviceUrl,hmm)
    mbsc = jmxc.getMBeanServerConnection
   
  }
  
  def getDomains() : Array[String] = {
    return mbsc.getDomains
  }
  
  def getBeanOperations(oName : ObjectName, jmxBean : JmxBean) : JmxBean = {
    val mInfo = mbsc.getMBeanInfo(oName)
     val jOpps = scala.collection.mutable.ListBuffer.empty[JmxOperation]
    for (mOpp <- mInfo.getOperations) {
      val jOpp = new JmxOperation
      jOpp.operationName = mOpp.getName
      jOpp.operationReturnType = mOpp.getReturnType
      val params = scala.collection.mutable.ListBuffer.empty[Tuple2[String,String]]
      
      mOpp.getSignature.foreach(x => params += new Tuple2(x.getName, x.getType))
      jOpp.operationParams = params.toList
      jOpps += jOpp
    }
    jmxBean.BeanOperations = jOpps.toList
    return jmxBean
  }
  
  def getBeanAttributes(oName : ObjectName, jmxBean : JmxBean) : JmxBean = {
    var jBean : JmxBean = jmxBean
    val mInfo = mbsc.getMBeanInfo(oName)
    val mAttrs = mInfo.getAttributes
    val attrMap = new HashMap[String,String]
    for (mAttr <- mAttrs) {
      try {
      val attr = mbsc.getAttribute(oName, mAttr.getName)
      attrMap += mAttr.getName -> attr.toString
      } catch {
        case ex : Exception => 
      }
    }
    
    
    jBean.BeanProperties = attrMap
    return jBean
  }
  
  def getBeanWithName(beanName : String) : JmxBean = {
    var jBean = new JmxBean
    val oName = new ObjectName(beanName)
    jBean.BeanName = beanName
    jBean = getBeanAttributes(oName,jBean)
    jBean = getBeanOperations(oName,jBean)
    
    return jBean
    
    
  }
  
  def getSpecifiedBeans(filters : List[String]) : List[JmxBean] = {
    var oNames = mbsc.queryNames(null, null)
    
    var objNames = oNames.toArray
    
    val jmxBeans = scala.collection.mutable.ListBuffer.empty[JmxBean]
    //Get every JmxBean
    for (objName  <- objNames) {
      
      var jBean = new JmxBean
      var oName = objName.asInstanceOf[ObjectName]
      
      jBean.BeanName = oName.getCanonicalName
      jBean = getBeanAttributes(oName,jBean)
      jBean = getBeanOperations(oName,jBean)
      jmxBeans += jBean
      
    }
    val typeBeans = scala.collection.mutable.ListBuffer.empty[JmxBean]
    val filteredBeans = scala.collection.mutable.ListBuffer.empty[JmxBean]
    //Loop through JmxBeans and filter them based on filters
    for (filter <- filters) {
      val filteredList = jmxBeans.filter(x => x.BeanName.contains(filter))
      if (filteredList.size > 0) {
        var jbean = new JmxBean 
        for (filteredBean <- filteredList) {
          filteredBean.BeanType = filter
          filteredBeans += filteredBean
        }
        jbean.BeanType = filter
        jbean.SubBeans = filteredBeans.toList
        typeBeans += jbean
      }
    }
    
    return typeBeans.toList
  }
  
}
